package cn.zhuama.user.service.impl;

import cn.zhuama.basic.content.Content;
import cn.zhuama.basic.util.*;
import cn.zhuama.exception.businessException;
import cn.zhuama.system.domain.Menu;
import cn.zhuama.system.mapper.PermissionMapper;
import cn.zhuama.system.service.IMenuService;
import cn.zhuama.user.domain.Logininfo;
import cn.zhuama.user.domain.User;
import cn.zhuama.user.domain.Wxuser;
import cn.zhuama.user.dto.BinderDto;
import cn.zhuama.user.mapper.LogininfoMapper;
import cn.zhuama.user.mapper.UserMapper;
import cn.zhuama.user.mapper.WxuserMapper;
import cn.zhuama.user.service.ILogininfoService;
import cn.zhuama.basic.service.impl.BaseServiceImpl;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.security.PrivateKey;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 业务实现类：
 */
@Service
@Transactional(readOnly = true ,propagation = Propagation.SUPPORTS)
public class LogininfoServiceImpl extends BaseServiceImpl<Logininfo> implements ILogininfoService {

    @Autowired
    private LogininfoMapper logininfoMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WxuserMapper wxuserMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private IMenuService menuService;
    @Override
    public AjaxResult account(Logininfo accDto) throws Exception {
        /*2.逻辑判断*/
        Logininfo dbLogin = logininfoMapper.selectByUsernameAndType(accDto);
        if(dbLogin==null){
            throw new businessException("用户不存在");
        }
        String inpPss = Md5Utils.encrypByMd5(accDto.getPassword() + dbLogin.getSalt());
        if(!inpPss.equals(dbLogin.getPassword())){
            throw new businessException("密码输入错误");
        }
        /*3.业务实现*/
        //String token = UUID.randomUUID().toString();
        /*存入redis*/
        //redisTemplate.opsForValue().set(token,dbLogin,30, TimeUnit.MINUTES);
        /*返回给前端*/
        Map<String, Object> map = new HashMap<>();
        dbLogin.setSalt(null);
        dbLogin.setPassword(null);
        //map.put("token",token);

        LoginData loginData = new LoginData();
        /*存入logininfo*/
        loginData.setLogininfo(dbLogin);
        /*拿到用户的菜单及权限*/
        List<Menu> menus  = menuService.loadMenuTreeByLoginInfoId(dbLogin.getId());
        /*拿到用户的权限*/
        List<String> permissions = permissionMapper.selectPermissionByLoginInfoId(dbLogin.getId());
        loginData.setPermissions(permissions);
        loginData.setMenus(menus);

        PrivateKey privateKey = RsaUtils.getPrivateKey(JwtUtils.class.getClassLoader().getResource("auth_rsa.pri").getFile());
        /*1.2打印私钥*/
        System.out.println("privateKey:   "+privateKey);
        /*1.3通过私钥加密内容  得到token    loginInfo   menus  permission*/
        String jwtToken = JwtUtils.generateTokenExpireInMinutes(loginData, privateKey, 3600);
        map.put("token",jwtToken);
        map.put("logininfo",dbLogin);
        map.put("permissions",permissions);
        map.put("menus",menus);

        return AjaxResult.me().setData(map).setMessage("登录成功即将跳转");


    }

    @Override
    public AjaxResult wechat(String code) throws Exception {
        System.out.println(code);
        String url = Content.url.replace(   "APPID", Content.APPID).replace("SECRET", Content.SECRET).replace("CODE",code);
        String jsonStr = HttpUtil.httpGet(url);
        JSONObject jsonObject =JSONObject.parseObject(jsonStr);
        String openid = jsonObject.getString("openid");
        String access_token = jsonObject.getString("access_token");
        Wxuser wxuser = wxuserMapper.selectByOpenId(openid);
        if(wxuser!=null){
            Logininfo dbLogin = logininfoMapper.selectByUserId(wxuser.getUserId());
           /* *//*3.业务实现*//*
            String token = UUID.randomUUID().toString();
            *//*存入redis*//*
            redisTemplate.opsForValue().set(token,dbLogin,30, TimeUnit.MINUTES);*/
            /*返回给前端*/
            Map<String, Object> map = new HashMap<>();
            dbLogin.setSalt(null);
            dbLogin.setPassword(null);
            //map.put("token",token);

            LoginData loginData = new LoginData();
            /*存入logininfo*/
            loginData.setLogininfo(dbLogin);
            /*拿到用户的菜单及权限*/
            List<Menu> menus  = menuService.loadMenuTreeByLoginInfoId(dbLogin.getId());
            /*拿到用户的权限*/
            List<String> permissions = permissionMapper.selectPermissionByLoginInfoId(dbLogin.getId());
            loginData.setPermissions(permissions);
            loginData.setMenus(menus);

            PrivateKey privateKey = RsaUtils.getPrivateKey(JwtUtils.class.getClassLoader().getResource("auth_rsa.pri").getFile());
            /*1.2打印私钥*/
            System.out.println("privateKey:   "+privateKey);
            /*1.3通过私钥加密内容  得到token    loginInfo   menus  permission*/
            String jwtToken = JwtUtils.generateTokenExpireInMinutes(loginData, privateKey, 3600);
            map.put("token",jwtToken);
            map.put("logininfo",dbLogin);
            map.put("permissions",permissions);
            map.put("menus",menus);
            return AjaxResult.me().setData(map).setMessage("登录成功即将跳转");
        }
        String data = "access_token="+access_token+"&openid="+openid;
        return AjaxResult.me().setSuccess(false).setData(data);
    }
/*输入的手机号码在系统中已经存在，只需要绑定*/
    @Override
    public AjaxResult binder(BinderDto binderDto) throws Exception {
        String phone = binderDto.getPhone();
        String verifyCode = binderDto.getVerifyCode();
        String accessToken = binderDto.getAccessToken();
        String openId = binderDto.getOpenId();
        Object o = redisTemplate.opsForValue().get(Content.PHONE_WXBINDER_PREFIX+phone);
        if(o==null ||!o.toString().split(":")[0].equalsIgnoreCase(verifyCode)){
            throw new businessException("验证码无效，请重新获取");
        }
        User user =  userMapper.selectByPhone(phone);
        if(user!=null){
            String url = Content.PERSON_URL.replace("ACCESS_TOKEN",accessToken).replace("OPENID",openId);
            String jsonStr =HttpUtil.httpGet(url);
            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
            Wxuser wxuser = new Wxuser();
            wxuser.setOpenid(jsonObject.getString("openid"));
            wxuser.setNickname(jsonObject.getString("nickname"));
            wxuser.setSex(jsonObject.getInteger("sex"));
            wxuser.setAddress(jsonObject.getString("province"));
            wxuser.setHeadimgurl(jsonObject.getString("headimgurl"));
            wxuser.setUnionid(jsonObject.getString("unionid"));
            wxuser.setUserId(user.getId());
            wxuserMapper.insert(wxuser);
            Logininfo dbLogin = logininfoMapper.selectByUserId(wxuser.getUserId());
           /* String token = UUID.randomUUID().toString();
            redisTemplate.opsForValue().set(token,dbLogin,30,TimeUnit.MINUTES);
            Map<String,Object> map = new HashMap<>();
            dbLogin.setSalt(null);
            dbLogin.setPassword(null);
            map.put("token",token);
            map.put("logininfo",dbLogin);*/
            Map<String, Object> map = new HashMap<>();
            dbLogin.setSalt(null);
            dbLogin.setPassword(null);
            //map.put("token",token);

            LoginData loginData = new LoginData();
            /*存入logininfo*/
            loginData.setLogininfo(dbLogin);
            /*拿到用户的菜单及权限*/
            List<Menu> menus  = menuService.loadMenuTreeByLoginInfoId(dbLogin.getId());
            /*拿到用户的权限*/
            List<String> permissions = permissionMapper.selectPermissionByLoginInfoId(dbLogin.getId());
            loginData.setPermissions(permissions);
            loginData.setMenus(menus);

            PrivateKey privateKey = RsaUtils.getPrivateKey(JwtUtils.class.getClassLoader().getResource("auth_rsa.pri").getFile());
            /*1.2打印私钥*/
            System.out.println("privateKey:   "+privateKey);
            /*1.3通过私钥加密内容  得到token    loginInfo   menus  permission*/
            String jwtToken = JwtUtils.generateTokenExpireInMinutes(loginData, privateKey, 3600);
            map.put("token",jwtToken);
            map.put("logininfo",dbLogin);
            map.put("permissions",permissions);
            map.put("menus",menus);
            return  AjaxResult.me().setData(map).setMessage("登录成功即将跳转");
        }
    return null;
    }
}
